﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GameNode
{
    class NodeGameLogic
   {
       private readonly GameField gameField;
       private readonly Drawer drawer;
       private readonly Random rnd;
       private List<ConsoleNode> nodes;
       private ConsoleNode target;
       private int[] winCounts;
       private int nodeCount;
       private readonly InputHandler _ih;


       public NodeGameLogic(GameField gameField, Drawer drawer, int nodeCount, InputHandler ih)
        {
            this.gameField = gameField;
            this.drawer = drawer;
            this.nodeCount = nodeCount;

            _ih = ih;
            _ih.KeyLeft += MoveNodeLeft;
            _ih.KeyRight += MoveNodeRight;
            _ih.KeyUp += MoveNodeUp;
            _ih.KeyDown += MoveNodeDown;


            rnd = new Random();
            nodes = new List<ConsoleNode>();
            target = GenerateRandomTarget((char) 1, ConsoleColor.White);

        }


        public void StartGame()
        {
            bool isGameOver = false;
            for(int z = 0; z<1000; z++)
            {
                nodes = new List<ConsoleNode>()
                {
                    new ConsoleNode(0,0,'@', ConsoleColor.Green)
                    //new ConsoleNode(0,0, 'X', ConsoleColor.Blue)

                };
                if (winCounts == null)
                    winCounts = new int[nodes.Count];
                RandomPlacement(nodes);
                Console.Clear();
                drawer.DrawListAndScore(nodes, gameField, 5, winCounts);
                bool isNewRound = false;
                do
                {
                    drawer.DrawGameField(gameField, '0');
                    drawer.DrawNodeList(nodes);
                    drawer.DrawNode(target);
                    _ih.QueryKB();
                    //nodes[1].Move(CheckPosition);
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (IsNodeOnTarget(nodes[i]))
                        {
                            winCounts[i]++;
                            isNewRound = true;
                            target = GenerateRandomTarget((char)1, ConsoleColor.White);
                        }
                    }
                    //drawer.DrawNodeList(nodes);
                    //drawer.DrawNode(target);
                    Thread.Sleep(50);
                }
                while (!isNewRound);

                //Console.ReadKey();

            }
            Console.ReadKey();
        }
    
       private ConsoleNode GenerateRandomNode(int nodeCount)
       {

           int randomX = 0;
           int randomY = 0;
           do
           {
               randomX = rnd.Next(gameField.X, gameField.Width + gameField.X);
               randomY = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

           } while (!IsPositionFree(randomX, randomY));

            return  new ConsoleNode(randomX, randomY, (char)(nodeCount + 41),
                                        (ConsoleColor)rnd.Next(1, 15));
       }

        private ConsoleNode GenerateRandomTarget(char symbol, ConsoleColor color)
        {

            int randomX = 0;
            int randomY = 0;
            do
            {
                randomX = rnd.Next(gameField.X, gameField.Width + gameField.X);
                randomY = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

            } while (!IsPositionFree(randomX, randomY));

            return new ConsoleNode(randomX, randomY, symbol, color);
        }

        private void GenerateRandomNodes()

        {
            for (int i = 0; i < nodeCount; i++)
            {
                nodes.Add(GenerateRandomNode(i));
            }
        }

       private bool IsPositionFree(int x, int y)
       {
            foreach (var nd in nodes)
            {
                if (nd.IsOnPossition(x,y))
                    return false;
            }
           return true;
       }

       private bool IsNodeOnTarget(ConsoleNode node)
       {
           if (node.X == target.X && node.Y == target.Y)
               return true;
           return false;
       }

        private void RandomPlacement(List<ConsoleNode> nodes)
        {
            int x=0;
            int y=0;
            foreach (var node in nodes)
            {
                do
                {
                    x = rnd.Next(gameField.X, gameField.Width + gameField.X);
                    y = rnd.Next(gameField.Y, gameField.Height + gameField.Y);

                } while (!IsPositionFree(x,y));
                node.X = x;
                node.Y = y;
            }
        }

       private Position CheckPosition(int x, int y)
       {
           if (!IsPositionFree(x, y))
               return Position.Node;
           if (!gameField.IsOnField(x, y))
               return Position.Border;
           return Position.Free;
       }

       private void MoveNodeLeft(object sender, EventArgs e)
       {
            if (IsPositionFree(nodes[0].X - 1, nodes[0].Y) &&
                gameField.IsOnField(nodes[0].X - 1, nodes[0].Y))
                nodes[0].MoveLeft();
       }

       private void MoveNodeRight(object sender, EventArgs e)
       {
            if (IsPositionFree(nodes[0].X + 1, nodes[0].Y) &&
                gameField.IsOnField(nodes[0].X + 1, nodes[0].Y))
                nodes[0].MoveRight();
        }


       private void MoveNodeUp(object sender, EventArgs e)
       {
            if (IsPositionFree(nodes[0].X, nodes[0].Y - 1) &&
                gameField.IsOnField(nodes[0].X, nodes[0].Y - 1))
                nodes[0].MoveUp();
       }

       private void MoveNodeDown(object sender, EventArgs e)
       {
            if (IsPositionFree(nodes[0].X, nodes[0].Y + 1) &&
                gameField.IsOnField(nodes[0].X, nodes[0].Y + 1))
                nodes[0].MoveDown();
        }
    }

    public enum Position
    {
        Node,
        Border,
        Free
    }

    


    //private void MoveNodeRandomly(ConsoleNode node)
    //{
    //     int randomMove = rnd.Next(1, 5);
    //     switch (randomMove)
    //     {
    //         case 1:
    //             {
    //                 //MoveUp
    //                 if (IsPositionFree(node.X, node.Y - 1) &&
    //                     gameField.IsOnField(node.X, node.Y - 1))
    //                     node.MoveUp();
    //             }
    //             break;

    //         case 2:
    //             {
    //                 //MoveDown
    //                 if (IsPositionFree(node.X, node.Y + 1) &&
    //                     gameField.IsOnField(node.X, node.Y + 1))
    //                     node.MoveDown();
    //             }
    //             break;

    //         case 3:
    //             {
    //                 //MoveLeft
    //                 if (IsPositionFree(node.X - 1, node.Y) &&
    //                     gameField.IsOnField(node.X - 1, node.Y))
    //                     node.MoveLeft();
    //             }
    //             break;

    //         case 4:
    //             {
    //                 //MoveRight
    //                 if (IsPositionFree(node.X + 1, node.Y) &&
    //                     gameField.IsOnField(node.X + 1, node.Y))
    //                     node.MoveRight();
    //             }
    //             break;
    //     }
    //}
}
